﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DnsChanger;
using DnsChanger.Exceptions;
using DnsChanger.Config;

namespace DnsChangerApp
{
    public partial class DnsChooser : Form
    {
        private const string m_manual = "Manual";

        public DnsChooser()
        {
            InitializeComponent();
        }

        private void DnsChooser_Load(object sender, EventArgs e)
        {
            LoadDnsServers();
        }

        private void LoadDnsServers()
        {
            cmbAvailableDns.Items.Clear();
            foreach (DnsServerElement dnsServer in DnsChangerConfiguration.Instance.DnsServers)
            {
                cmbAvailableDns.Items.Add(dnsServer.Name);
            }
            cmbAvailableDns.Items.Add(m_manual);
            cmbAvailableDns.SelectedIndex = 0;
            FillDnsServerList();
            FillCurrentList();
        }

        private void FillDnsServerList()
        {
            txtDnsServers.Text = "";
            txtDnsServers.ReadOnly = true;
            string provider = cmbAvailableDns.SelectedItem as string;

            if (provider == m_manual)
            {
                txtDnsServers.ReadOnly = false;
                return;
            }

            DnsServerElement dnsServer = DnsChangerConfiguration.Instance.DnsServers[provider];
            if (dnsServer.Servers.Count() == 0)
                txtDnsServers.Text = "";
            else
                txtDnsServers.Text = dnsServer.Servers.Aggregate((aggregate, nextServer) => aggregate += "\r\n" + nextServer);
        }

        private void FillCurrentList()
        {
            List<string> servers = DnsHelper.GetDnsServers();
            if (servers.Count == 0)
                txtCurrent.Text = "";
            else
                txtCurrent.Text = servers.Aggregate((output, item) => output += "\r\n" + item);
        }

        private void cmbAvailableDns_SelectedIndexChanged(object sender, EventArgs e)
        {
            FillDnsServerList();
        }

        private void btnApplyChanges_Click(object sender, EventArgs e)
        {
            string provider = cmbAvailableDns.SelectedItem as string;

            DnsServerElement server = null;

            if (provider == m_manual)
            {
                server = new DnsServerElement
                {
                    Name = "Manual",
                    ConfigServers = txtDnsServers.Lines.AsCsv()
                };
            }
            else
            {
                server = DnsChangerConfiguration.Instance.DnsServers[provider];
            }

            try
            {
                if (!DnsHelper.SetDnsServers(server.Servers))
                    MessageBox.Show("Changes require a reboot");
            }
            catch (InvalidServerException ex)
            {
                MessageBox.Show("Invalid server name '{0}'", ex.Message);
            }

            FillCurrentList();
        }

        private void btnSaveCurrent_Click(object sender, EventArgs e)
        {
            List<string> currentDnsServers = DnsHelper.GetDnsServers();
            DnsServerElement backupElement = DnsChangerConfiguration.Instance.DnsServers["Restore"];
            if (backupElement == null)
            {
                backupElement = new DnsServerElement();
                backupElement.Name = "Restore";
                backupElement.ConfigArgs = "restore";
            }
            backupElement.ConfigServers = currentDnsServers.AsCsv();
            backupElement.Info = currentDnsServers.AsCsv();
            DnsChangerConfiguration.Instance.DnsServers["Restore"] = backupElement;
            DnsChangerConfiguration.Instance.Save();
            MessageBox.Show("Saved current settings as 'Restore'.");
            LoadDnsServers();
        }
    }
}
